﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HAMath
{

    public class CreateGridFromBias
    {
        /// <summary>
        /// 计算  使用  Base和Max的Bias构建的网格分布情况   返回构建的相对于网格坐标系的点的分布     
        /// 出错或者数据无效  返回的 List< > result 的 Count=0
        /// </summary>
        /// <param name="length">长度 （起始点为0 结束点为 length）</param>
        /// <param name="bias">Bias值</param>
        /// <param name="baseCellSize">基本单元格长度</param>
        /// <param name="maxCellSize">最大单元格长度</param>
        /// <returns></returns>
     
        public static List<double> HasBaseLimitBiasGrid(double length, double bias, double baseCellSize, double maxCellSize)
        {
            List<double> result = new List<double>();

            result.Add(0.0);

            #region 首先进行一些必要的数据有效性检验

            if (length <= 0)
            {
                return result;
            }
            if (baseCellSize <= 0 || maxCellSize <= 0)
            {
                return result;
            }
            if (maxCellSize < baseCellSize)
            {
                return result;
            }

            #endregion


            try
            {
                //if (bias > 0)
                {
                    if (bias < 1)
                    {
                       //暂时按照平分为2

                        List<double> addCellLen = new List<double>();
                        double addCellTotalLen = 0.0;

                        int cellNum = 2;

                        double ableLength = length / (double)cellNum;


                        for (int i = 0; i < cellNum; i++)
                        {
                            addCellLen.Add(ableLength);
                            addCellTotalLen = addCellTotalLen + ableLength;
                        }


                        int coorIndex = result.Count - 1;

                        if (addCellLen.Count > 0)
                        {
                            for (int i = 0; i < addCellLen.Count; i++)
                            {
                                result.Add(result[coorIndex] + addCellLen[i]);

                                coorIndex = coorIndex + 1;

                            }
                        }



                    }
                    else if (bias == 1)
              
                    {
                        //平均分配

                        #region

                        List<double> addCellLen = new List<double>();
                        double addCellTotalLen = 0.0;

                        int cellNum = (int)Math.Ceiling(length /baseCellSize );

                        double ableLength = length / (double)cellNum;


                        for (int i = 0; i < cellNum ; i++)
                        {
                              addCellLen.Add(ableLength);
                              addCellTotalLen = addCellTotalLen + ableLength;
                        }


                        int coorIndex = result .Count -1;

                        if (addCellLen.Count > 0)
                        {
                            for (int i = 0; i <addCellLen .Count ; i++)
                            {
                                result.Add(result[coorIndex] + addCellLen[i]);

                                coorIndex = coorIndex + 1;

                            }
                        }

                        #endregion

                    }
                    else if (bias > 1)
                    {
                        //此种情况 X方向 向右逐渐稀疏变宽， Y方向 向上逐渐稀疏变宽
                        if (baseCellSize ==maxCellSize )
                        {
                            //平均分配成2个
                            #region

                            List<double> addCellLen = new List<double>();
                            double addCellTotalLen = 0.0;

                            int cellNum = 2;

                            double ableLength = length / (double)cellNum;


                            for (int i = 0; i < cellNum; i++)
                            {
                                addCellLen.Add(ableLength);
                                addCellTotalLen = addCellTotalLen + ableLength;
                            }


                            int coorIndex = result.Count - 1;

                            if (addCellLen.Count > 0)
                            {
                                for (int i = 0; i < addCellLen.Count; i++)
                                {
                                    result.Add(result[coorIndex] + addCellLen[i]);

                                    coorIndex = coorIndex + 1;

                                }
                            }

                            #endregion

                        }
                        else if (baseCellSize < maxCellSize)
                        {
                   

                            //再往点的右侧
                            List<double> addCellLengthRight = new List<double>();//记录添加的合理单元格的长度
                            double addCellTotalLengthRight = 0;//记录上述List中已经添加的cell的长度的总和

                            #region

                            if (length  <= baseCellSize )
                            {
                            }
                            else
                            {
                                for (int i = 1; true; i++)
                                {
                                    double cellLengthI;//合理的单元格的长度
                                    cellLengthI = Math.Pow(bias , i) * baseCellSize;

                                    if (cellLengthI <= maxCellSize ) // cell的 Max 允许添加
                                    {
                                        //判断剩余距离是否够添加该长度Cell
                                        if (length - baseCellSize - addCellTotalLengthRight >= cellLengthI)//距离足够
                                        {
                                            addCellLengthRight.Add(cellLengthI);
                                            addCellTotalLengthRight = addCellTotalLengthRight + cellLengthI;
                                        }
                                        else
                                        {
                                            //距离不够添加该cell

                                            addCellLengthRight.Add(length - baseCellSize - addCellTotalLengthRight);
                                            addCellTotalLengthRight = addCellTotalLengthRight + length - baseCellSize  - addCellTotalLengthRight;


                                            #region 下面的算法已经被上面几句简化方法代替


                                            //if (addCellLengthRight.Count > 0)
                                            //{
                                            //    #region

                                            //    if (x1ToRight - p1BaseSize * 0.5 - addCellTotalLengthRight >= addCellLengthRight[addCellLengthRight.Count - 1])
                                            //    {

                                            //        addCellLengthRight.Add(x1ToRight - p1BaseSize * 0.5 - addCellTotalLengthRight);
                                            //        addCellTotalLengthRight = addCellTotalLengthRight + x1ToRight - p1BaseSize * 0.5 - addCellTotalLengthRight;


                                            //    }
                                            //    else
                                            //    {

                                            //        addCellTotalLengthRight = addCellTotalLengthRight - addCellLengthRight[addCellLengthRight.Count - 1];
                                            //        addCellLengthRight.RemoveAt(addCellLengthRight.Count - 1);

                                            //        //剩余距离分配

                                            //        if (x1ToRight - p1BaseSize * 0.5 - addCellTotalLengthRight > p1MaxSize)
                                            //        {

                                            //            double lenTotal = x1ToRight - p1BaseSize * 0.5 - addCellTotalLengthRight;

                                            //            for (int num = 1; true; num++)
                                            //            {
                                            //                //计算分割为几个单元格比较合适

                                            //                double everageCellLen = (double)((decimal)lenTotal / num);

                                            //                if (everageCellLen > p1MaxSize)
                                            //                {
                                            //                    double everage = (double)((decimal)lenTotal / (num + 1));
                                            //                    if (everage <= addCellLengthRight[addCellLengthRight.Count - 1])
                                            //                    {
                                            //                        //添加上吧
                                            //                        for (int index = 0; index < num; index++)
                                            //                        {
                                            //                            addCellLengthRight.Add(everageCellLen);
                                            //                            addCellTotalLengthRight = addCellTotalLengthRight + everageCellLen;
                                            //                        }

                                            //                        break;

                                            //                    }
                                            //                    else
                                            //                    {
                                            //                        //继续找
                                            //                        continue;
                                            //                    }

                                            //                }
                                            //                else
                                            //                {
                                            //                    //就这样分配吧

                                            //                    for (int index = 0; index < num; index++)
                                            //                    {
                                            //                        addCellLengthRight.Add(everageCellLen);
                                            //                        addCellTotalLengthRight = addCellTotalLengthRight + everageCellLen;
                                            //                    }

                                            //                    break;
                                            //                }


                                            //            }// for (int num = 2; true ; num++)  结束


                                            //        }
                                            //        else
                                            //        {
                                            //            //剩余的分配为1个

                                            //            addCellLengthRight.Add(x1ToRight - p1BaseSize * 0.5 - addCellTotalLengthRight);
                                            //            addCellTotalLengthRight = addCellTotalLengthRight + x1ToRight - p1BaseSize * 0.5 - addCellTotalLengthRight;

                                            //        }

                                            //        //break;
                                            //    }

                                            //    break;

                                            //    #endregion


                                            //}
                                            //else
                                            //{
                                            //    addCellLengthRight.Add(x1ToRight - p1BaseSize * 0.5 - addCellTotalLengthRight);
                                            //    addCellTotalLengthRight = addCellTotalLengthRight + x1ToRight - p1BaseSize * 0.5 - addCellTotalLengthRight;

                                            //}

                                            #endregion

                                            break;
                                        }
                                    }
                                    else
                                    {
                                        //例如 5,2,20  达到了25   MaxSize不允许

                                        //如果正好能够平均分配整数个MaxSize的单元格， 

                                        double ableLen = (length - baseCellSize  - addCellTotalLengthRight);//剩余距离

                                        int cellNum20 = (int)Math.Ceiling(ableLen % maxCellSize);//能够按照每个MaxSize正好分配  防止0.25等的情况


                                        if (ableLen >= maxCellSize && cellNum20 == 0)
                                        {
                                            //平均分配

                                            int number = (int)(ableLen / maxCellSize);
                                            for (int index = 0; index < number; index++)
                                            {
                                                addCellLengthRight.Add(maxCellSize);
                                                addCellTotalLengthRight = addCellTotalLengthRight + maxCellSize;
                                            }

                                            break;
                                        }
                                        else
                                        {

                                            //剩余距离分配

                                            if (length - baseCellSize  - addCellTotalLengthRight <= maxCellSize)
                                            {
                                                addCellLengthRight.Add(length - baseCellSize  - addCellTotalLengthRight);
                                                addCellTotalLengthRight = addCellTotalLengthRight + length - baseCellSize  - addCellTotalLengthRight;
                                            }
                                            else
                                            {
                                                double len = length - baseCellSize  - addCellTotalLengthRight;
                                                double cellLength;
                                                for (int num = 1; true; num++)
                                                {
                                                    #region 寻找合适的单元格分配

                                                    cellLength = (double)((decimal)len / num);

                                                    if (cellLength <= maxCellSize)
                                                    {

                                                        for (int n = 0; n < num; n++)
                                                        {
                                                            addCellLengthRight.Add(cellLength);
                                                            addCellTotalLengthRight = addCellTotalLengthRight + cellLength;
                                                        }

                                                        break;
                                                    }
                                                    else
                                                    {
                                                        continue;
                                                    }

                                                    #endregion
                                                }
                                            }


                                            #region 下面的方法已经被上面几句简化方法替换掉


                                            ////从已经添加的cell集合中取出最后一个添加的cell的长度，加入剩余长度中进行分配

                                            //if (addCellLengthRight.Count > 0)
                                            //{
                                            //    addCellTotalLengthRight = addCellTotalLengthRight - addCellLengthRight[addCellLengthRight.Count - 1];
                                            //    addCellLengthRight.RemoveAt(addCellLengthRight.Count - 1);
                                            //}

                                            //double len = x1ToRight - p1BaseSize * 0.5 - addCellTotalLengthRight;//剩余距离

                                            //if (len <= p1MaxSize)
                                            //{
                                            //    //分成一个即可
                                            //    addCellLengthRight.Add(len);
                                            //    addCellTotalLengthRight = addCellTotalLengthRight + len;

                                            //}
                                            //else
                                            //{
                                            //    //if (len > p1MaxSize)

                                            //    double cellLength;

                                            //    #region

                                            //    for (int num = 1; true; num++)
                                            //    {
                                            //        #region 寻找合适的单元格分配  逐渐增加单元格的个数

                                            //        cellLength = (double)((decimal)len / num);

                                            //        if (cellLength <= p1MaxSize)
                                            //        {
                                            //            if (cellLength >= addCellLengthRight[addCellLengthRight.Count - 1])
                                            //            {
                                            //                addCellLengthRight.Add(cellLength);
                                            //                addCellTotalLengthRight = addCellTotalLengthRight + cellLength;

                                            //                break;

                                            //            }
                                            //            else
                                            //            {
                                            //                //下面的处理有点不合理  暂时这样吧

                                            //                #region

                                            //                if (num == 1)
                                            //                {
                                            //                    addCellLengthRight.Add(cellLength);
                                            //                    addCellTotalLengthRight = addCellTotalLengthRight + cellLength;

                                            //                    break;

                                            //                }
                                            //                else if (num > 1)
                                            //                {

                                            //                    cellLength = (double)((decimal)len / (num - 1));//即使结果 > MaxSize 也这样做

                                            //                    addCellLengthRight.Add(cellLength);
                                            //                    addCellTotalLengthRight = addCellTotalLengthRight + cellLength;

                                            //                    break;

                                            //                }

                                            //                #endregion

                                            //            }
                                            //        }
                                            //        else
                                            //        {
                                            //            continue;
                                            //        }

                                            //        #endregion

                                            //    }//   for (int num = 1; true; num++)结束

                                            //    #endregion

                                            //}
                                            #endregion

                                            break;

                                        }

                                    }

                                }// for (int i = 1; true; i++) 结束

                            }//       if (x1ToRight > p1BaseSize * 0.5)结束


                            #endregion

                            //整理添加结果

                            if (addCellLengthRight.Count > 0)
                            {
                                //首先添加点所在的单元格的右侧坐标

                                result.Add(baseCellSize);

                                int cellIndex = result.Count - 1;
                                for (int i = 0; i < addCellLengthRight.Count; i++)
                                {
                                    result.Add(result[cellIndex] + addCellLengthRight[i]);
                                    cellIndex = cellIndex + 1;
                                }
                            }
                            else
                            {
                                result .Add(length );
                            }

                        }


                    }// else if (bias > 1) 结束
                }
                //else
                //{
                //    //bias<=0 


                //}

                return result;

            }
            catch
            {
                result = new List<double>();
                return result;
            }



        }

        /// <summary>
        /// 计算 不使用   Base和Max的Bias构建的网格分布情况   返回构建的相对于网格坐标系的点的分布     
        /// 出错或者数据无效  返回的  List< > result 的 Count=0
        /// </summary>
        /// <param name="length">长度 （起始点为0 结束点为 length） </param>
        /// <param name="bias">Bias值</param>
        /// <param name="numCells">单元格数</param>
        /// <returns></returns>
        public static List<double> NoBaseLimitBiasGrid(double length, double bias, int numCells)
        {
            List<double> result = new List<double>();

            result.Add(0.0);

            #region  首先进行一些必要的数据有效性检验

            if (length <= 0)
            {
                return result;
            }
            if (numCells <= 0)
            {
                return result;
            }

            #endregion

            try
            {

                //if (bias > 0)
                {
                    if (bias < 1)
                    {
                        //此种情况 X方向 向右逐渐稠密变窄， Y方向 向上逐渐稠密变窄
                        if (bias <= 0)
                        {
                            //按照bias=1处理

                            double cellLength;
                            double len = length;
                            int num = numCells;
                            cellLength = (double)((decimal)len / num);

                            if (numCells == 1)
                            {
                                result.Add(len);
                            }
                            else if (num > 1)
                            {
                                for (int i = 0; i < numCells; i++)
                                {
                                    if (i == numCells - 1)
                                    {
                                        result.Add(len);
                                    }
                                    else
                                    {
                                        result.Add(result[result.Count - 1] + cellLength);
                                    }
                                }
                            }

                        }
                        else
                        {
                            double temp = 1.0;

                            if (numCells == 1)
                            {
                                result.Add(length);
                            }
                            else if (numCells > 1)
                            {
                                for (int i = 0; i < numCells; i++)
                                {
                                    if (i > 0)
                                    {
                                        temp = temp + Math.Pow(bias, i);
                                    }
                                }

                                double cellOneLen = length / temp;

                                for (int i = 0; i < numCells; i++)
                                {
                                    //添加单元格
                                    result.Add(result[result.Count -1]+  cellOneLen * Math.Pow(bias, i));
                                }

                            }
                        
                        }


                    }
                    else if (bias == 1)
                    {
                        #region

                        double cellLength;
                        double len = length;
                        int num = numCells;
                        cellLength = (double)((decimal)len / num);

                        if (numCells == 1)
                        {
                            result.Add(len);
                        }
                        else if (num > 1)
                        {
                            for (int i = 0; i < numCells; i++)
                            {
                                if (i == numCells - 1)
                                {
                                    result.Add(len);
                                }
                                else
                                {
                                    result.Add(result[result.Count - 1] + cellLength);
                                }
                            }
                        }

                        #endregion

                    }
                    else if (bias > 1)
                    {
                        //此种情况 X方向 向右逐渐稀疏变宽， Y方向 向上逐渐稀疏变宽

                        //假设第一个单元格的长度为 x 则numCells个单元格的长度之和等于length
                        //有 length=x+x*bias+x*bias*bias+x*bias*bias*bias..........

                        #region

                        double temp = 1.0;

                        if (numCells == 1)
                        {
                            result.Add(length);
                        }
                        else if (numCells > 1)
                        {
                            for (int i = 0; i < numCells; i++)
                            {
                                if (i >0)
                                {
                                    temp = temp + Math.Pow(bias, i);
                                }
                            }

                            double cellOneLen = length / temp;

                            for (int i = 0; i < numCells ; i++)
                            {
                                //添加单元格
                                result.Add(result[result.Count - 1] + cellOneLen * Math.Pow(bias, i));   
                            }

                        }

                        #endregion

                    }//bias>1结束
                }
                //else
                //{
                //    //bias<=0 


                //}


                return result;


            }
            catch
            {

                result = new List<double>();
                return result;
            }


        }



    }
}
